package com.uxsino.rule.nms.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uxsino.rule.model.CompsRange;
import com.uxsino.rule.model.NumberCompareWay;
import com.uxsino.rule.nms.model.NmsCaller;
import com.uxsino.rule.nms.model.NmsReport;
import com.uxsino.rule.nms.model.SubRuleReport;
import com.uxsino.rule.nms.strategy.dto.IndicatorTableDto;
import com.uxsino.rule.nms.strategy.dto.RuleDto;
import com.uxsino.rule.nms.strategy.dto.ValidateAlertInfo;
import com.uxsino.rule.nms.strategy.dto.ValidateMsg;
import com.uxsino.rule.nms.validate.NumberValidator;

import lombok.NoArgsConstructor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * 数量统计的策略暂不支持自定义通知模板
 */
@NoArgsConstructor
public class SumStrategyHandler extends BaseStrategy {

    private static Logger logger = LoggerFactory.getLogger(SumStrategyHandler.class);

    public SumStrategyHandler(NmsCaller caller) {
        this.callData = caller;
    }

    /**
     * 匹配校验逻辑并返回校验结果
     *
     * @param setting
     * @param value
     */
    @Override
    public boolean ruleMatch(JSONObject setting, String... value) {
        // Double value = result.getDouble(SUM);

        Double _value = null;
        try {
            _value = Double.parseDouble(value[0]);
        } catch (NumberFormatException e) {
            logger.error("规则引擎-数量统计校验错误！", e);
        }
        NumberCompareWay compareWay = NumberCompareWay.valueOf(setting.getString("compareWay"));
        Double target = setting.getDouble("value");
        NumberValidator validator = new NumberValidator(compareWay, _value, target);
        boolean warning = validator.validate();
        return warning;
    }

    @Override
    public String createAlertRange(JSONObject setting) {
        int target = setting.getInteger("value");
        NumberCompareWay compareWay = NumberCompareWay.valueOf(setting.getString("compareWay"));
        return compareWay.getSign() + target;
    }

    @Override
    public NmsReport holisticVerifyProcess() {
        RuleDto rule = callData.getRule();
        JSONArray array = callData.getIndValue();
        IndicatorTableDto indicator = callData.getIndicator();
        CompsRange compsRange = "LIST".equals(indicator.getIndicatorType())
                && (indicator.getNoKey() != null && indicator.getNoKey()) ? CompsRange.all : rule.getCompsRange();
        ValidateMsg msg = getMsg();
        boolean alertStatus = false;
        List<String> componentIds = getComponentIds(rule);
        // 部件范围为“不限”时，没有指定的部件，是动态匹配指标值所有数据。此处不设置告警部件，否则可能会使告警无法恢复
        // msg.setComponentId(componentIds.stream().distinct().collect(Collectors.joining(",")));
        List<ValidateAlertInfo> alertInfoList = new ArrayList<>();
        for (Object obj : JSON.parseArray(rule.getSettings())) {
            JSONObject setting = JSON.parseObject(obj.toString());
            int sum = 0;
            if (CompsRange.all.equals(compsRange)) {
                sum = array.size();
            } else {
                for (Object object : array) {
                    JSONObject result = JSONObject.parseObject(object.toString());// 当前检测数据
                    String currentComponentId = result.containsKey("identifier") ? result.getString("identifier") : "";
                    if (componentIds.contains(currentComponentId)) {
                        sum++;
                    }
                }
            }
            msg.setCurrentValue(sum + "");
            boolean warning = ruleMatch(setting, sum + "");
            if (warning) {
                alertStatus = true;
            }
            ValidateAlertInfo alert = dealWithValidateResult(setting, warning, msg);
            alertInfoList.add(alert);
        }
        NmsReport report = new NmsReport();
        report.setIndStatus(alertStatus ? hit : not_hit);
        report.setAlertStatus(alertStatus);
        report.setAlertList(alertInfoList);
        return report;
    }

    @Override
    public SubRuleReport support4Holistic() {
        NmsReport report = holisticVerifyProcess();
        SubRuleReport sr = new SubRuleReport();
        sr.setAlertStatus(report.getAlertStatus());
        if (sr.getAlertStatus()) {
            StringBuffer alertContentBuffer = new StringBuffer();
            alertContentBuffer.append(callData.getIndicator().getLabel());
            alertContentBuffer.append(callData.getRule().getCompareType().getText());
            alertContentBuffer.append("异常");
            sr.setSubAlertContent(alertContentBuffer.toString());
        }
        return sr;
    }

    @Override
    public SubRuleReport support4Modular(JSONObject compData) {
        RuleDto rule = callData.getRule();
        boolean valiStatus = false;
        String currentComponentId = compData.containsKey("identifier") ? compData.getString("identifier") : "";
        for (Object obj : JSON.parseArray(rule.getSettings())) {
            JSONObject setting = JSON.parseObject(obj.toString());
            boolean warning = verifierUnit(compData, currentComponentId, rule, setting, null, new ValidateMsg(), false);
            valiStatus = valiStatus || warning;
        }
        SubRuleReport srr = new SubRuleReport();
        srr.setAlertStatus(valiStatus);
        if (valiStatus) {
            StringBuffer alertContentBuffer = new StringBuffer();
            alertContentBuffer.append(callData.getIndicator().getLabel());
            alertContentBuffer.append(callData.getRule().getCompareType().getText());
            alertContentBuffer.append("异常");
            srr.setSubAlertContent(alertContentBuffer.toString());
        }
        return srr;
    }
}